package cn.edu.cuit.elena.common;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Writer;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.io.SAXReader;

import cn.edu.cuit.elena.trace.Tracer;

public class FileHandler
{
    public static void generatePropertyFile( Configurable configurable, String filePath )
    {
        Map<String, String> properties = configurable.getProperties();
        Writer writer = openWriter( filePath );
        try
        {
            for( String key : properties.keySet() )
            {
                writer.write( key + SackConstants.EQUAL_SIGN + properties.get( key ) + "\n" );
            }

            closeWriter( writer );
        }
        catch( IOException e )
        {
            throw new FileHandlingException( e.getMessage() );
        }
    }

    private static void closeWriter( Writer writer )
    {
        try
        {
            writer.close();
        }
        catch( Exception e )
        {
            throw new FileHandlingException( e.getMessage() );
        }
    }

    private static Writer openWriter( String filePath )
    {
        File file = new File( filePath );
        try
        {
            Writer out = new FileWriter( file );
            BufferedWriter bufferedWriter = new BufferedWriter( out );
            return bufferedWriter;
        }
        catch( IOException e )
        {
            throw new FileHandlingException( e.getMessage() + ". Root exception : " + e.getClass() );
        }
    }

    /**
     * To get the resources file by <code>classpath</code> relative path.
     * 
     * @throws IOException
     * */
    private static InputStream openSourceStream( String filePath ) throws IOException
    {
        try
        {
            Tracer.debugTrace( FileHandler.class, "Open Source file : "
                + Thread.currentThread().getContextClassLoader().getResource( filePath ).getPath(), null );
            return Thread.currentThread().getContextClassLoader().getResource( filePath ).openStream();
        }
        catch( IOException e )
        {
            Tracer.fatalTrace( FileHandler.class,
                "Can't open SourceFile "
                    + Thread.currentThread().getContextClassLoader().getResource( filePath ).getPath() + " due to : "
                    + e.getMessage(), e );
            return null;
        }
    }

    public static BufferedReader openReader( String path )
    {
        try
        {
            Tracer.debugTrace( FileHandler.class, "Open Reader from file : "
                + Thread.currentThread().getContextClassLoader().getResource( path ).getPath(), null );
            return new BufferedReader( new InputStreamReader( openSourceStream( path ) ) );
        }
        catch( IOException e )
        {
            Tracer.fatalTrace(
                FileHandler.class,
                "Can't open Reader from file "
                    + Thread.currentThread().getContextClassLoader().getResource( path ).getPath() + " due to : "
                    + e.getMessage(), e );
            return null;
        }
    }

    public static Map<String, String> loadPropertyFile( String path )
    {
        BufferedReader reader = openReader( path );
        Map<String, String> map = new HashMap<String, String>();
        Properties properties = new Properties();
        try
        {
            properties.load( reader );
        }
        catch( IOException e )
        {
            new FileHandlingException( e.getMessage(), e );
        }
        for( Object o : properties.keySet() )
        {
            String key = (String) o;
            map.put( key, properties.getProperty( key ) );
        }
        return map;
    }

    public static Document loadXmlFile( String path ) throws DocumentException
    {
        SAXReader reader = new SAXReader();
        return reader.read( openReader( path ) );
    }
}
